#include<cstdio>
#include<string>
#include<cstring>
#include<cstdlib>
#include<unistd.h>
#include<sys/wait.h>


#define BASE_SIZE 256
//命令行参数
char *gargv[BASE_SIZE];
int gargc;

//最近一次进程的运行结果
int lastcode=0;
#define ERROR 1 

//当前文件路径
char cwd[BASE_SIZE];
char cwdenv[BASE_SIZE];
std::string getusr()
{
    std::string name=getenv("USER");
    return name.empty()?"None":name;
}

std::string gethost()
{
    std::string hostname=getenv("HOSTNAME");
    return hostname.empty()?"None":hostname;
}

std::string getcwd()
{
   if( getcwd(cwd,BASE_SIZE)==nullptr)
   {
       strcpy(cwd,"Node");
   }
   snprintf(cwdenv,BASE_SIZE,"PWD=%s",cwd);
   putenv(cwdenv);
    return cwd;
}

void  PrintCommandLine()
{
   char buf[BASE_SIZE]={0};
   snprintf(buf,BASE_SIZE,"[%s@%s %s]:"\
           ,getusr().c_str(),gethost().c_str(),getcwd().c_str());
   fputs(buf,stdout);
   fflush(stdout);
}

bool GetUsrCommand(char commandbuf[])
{
    if(fgets(commandbuf,BASE_SIZE,stdin)==nullptr)
    {
        return false;
    }
    commandbuf[strlen(commandbuf)-1]='\0';
    return true;

}

void ParseUsrCommand(char* commandbuf)
{
    memset(gargv,0,BASE_SIZE*sizeof(commandbuf[0]));
    gargc=0;
    gargv[gargc++]=strtok(commandbuf," ");
    while(bool(gargv[gargc]=strtok(nullptr," ")))
    {
        gargc++;
    }
}

bool CheckAndExecuteBulitCommand()//判断一下用户输入的是否是内建命令
{
    if(gargc==2&&strcmp(gargv[0],"cd")==0)
    {
        if(chdir(gargv[1])==-1)
        {
            printf("No such file of dirtory");
            lastcode=ERROR;
            return true;
        }
        lastcode=0;
        return true;
        
    }
    else if(gargc==2&&strcmp(gargv[0],"echo")==0)
    {
        if(strcmp(gargv[1],"$?")==0)
        {
            printf("%d\n",lastcode);
        }
        else
        {
            printf("%s\n",gargv[1]);
        }
        lastcode=0;
        return true;
    }

    return false;
}

void ExecuteUsrCommand()
{
    pid_t id=fork();
    if(id==0)
    {
        execvp(gargv[0],gargv);
        exit(1);
    }
    else if(id>0)
    {
        int status=0;
        waitpid(id,&status,0);
        lastcode=WEXITSTATUS(status);
    }
}

void debug()
{
    int i=0;
    while(gargv[i])
    {
        printf("%s\n",gargv[i]);
        i++;
    }
    printf("%d\n",gargc);
}

int main()
{
    char commandbuf[BASE_SIZE];
    while(true)
    {
        //1. 命令行提示符
        PrintCommandLine();

        //2. 获取用户命令
        if(GetUsrCommand(commandbuf)==false)
        {
            continue;
        }

        //3. 解析用户命令
        ParseUsrCommand(commandbuf);

        //4. 执行用户命令
        if(CheckAndExecuteBulitCommand())//判断一下用户输入的是否是内建命令
        {
            continue;
        }
        ExecuteUsrCommand();
    }
    return 0;
}
